var ovo = (function(){

    /* ajax */
    function ovo_ajax(opt){
        /*请求对象*/
        var xhr = window.XMLHttpRequest?
            new XMLHttpRequest :
            new ActiveXObject('Microsoft.XMLHTTP');

        /*如果没有http异步请求对象，对外抛出个异常*/
        if(!xhr){
            throw new Error('当前浏览器不支持异步发起HTTP请求');
        }


        /* 对配置进行处理 */
        opt = opt || {};
        var type = (opt.type || 'GET').toUpperCase(),
            url = opt.url,
            async = '' + opt.async === 'false' ? false : true,
            dataType = opt.dataType || 'JSON',
            data = opt.data || null,
            jsonp = opt.jsonp || 'cb',  //?
            jsonpCallback = opt.jsonpCallback || 'jQuery'+randomNum(), //?
            timeout = opt.timeout || 30000,
            success = opt.success || function(){},
            error = opt.error || function(){},
            complete = opt.complete || function(){},
            t = null;   //?

        /*如果没有传url，对外抛出个异常*/
        if(!url){
            throw new Error('请填写url请求路径');
        }

        if(dataType.toUpperCase() === 'JSONP' && type !== 'GET'){
            throw new Error('如果dataType为JSONP，type请您设置get或者不设置');
        }
        if(dataType.toUpperCase() === 'JSONP'){
            var oScript = document.createElement("script");
            oScript.src = url.indexOf("?") === -1?
                url+'?'+jsonp+'='+jsonpCallback:
                url+'&'+jsonp+'='+jsonpCallback;
            document.body.appendChild(oScript);
            document.body.removeChild(oScript);
            window[jsonpCallback] = function(){
                success(data);
            }
            return;
        }

        /*请求响应*/
        xhr.onreadystatechange = function(){
            if(xhr.readyState === 4){

                if((xhr.status >= 200 && xhr.status <300) || xhr.status === 304){
                    switch (dataType.toUpperCase()) {
                        case 'JSON':
                            success(JSON.parse(xhr.responseText));
                            break;
                        case 'TEXT':
                            success(xhr.responseText);
                            break;
                        case 'XML':
                            success(xhr.responseXML);
                            break;
                        default:
                            success(JSON.parse(xhr.responseText));
                    }
                }
            }else{
                /*失败回调*/
                error(xhr.status);
            }
            //最后都要走的回调
            complete();
            clearTimeout(t);   //?
            t = null;
            xhr = null;
        }


        /*发送设置*/
        xhr.open(type,url,async);
        /*设置请求头*/
        opt.type === 'POST' && xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded');
        /*发送*/
        xhr.send(opt.type === 'GET'?null:jsonToUrlData(data));

        t = setTimeout(function(){
            throw new Error("本次请求已超时，API地址："+url);
            xhr.abort();
            clearTimeout(t);
            t = null;
            xhr = null;
        },timeout);

        /*请求响应*/
        xhr.onreadystatechange = function(){
            if(xhr.readyState === 4 && xhr.status === 200){
                /*成功回调*/
                success(JSON.parse(xhr.responseText))
            }else{
                /*失败回调*/
                error(xhr.status);
            }
            //最后都要走的回调
            complete();
        }
    }

    //json转urldata数据
    function jsonToUrlData(data){
        if(typeof data === 'string'){
            return data;
        }else{
            var str = '';
            for(key in data){
                str += key+'='+data[key]+'&'
            }
            return str.replace(/&$/,'');
        }
    }
    function randomNum(){
        var num = '';
        for(var i=0;i<20;i++){
            num+=Math.floor(Math.random()*10);
        }
        return num;
    }

    return {
        ajax(opt){
            ovo_ajax(opt)
        },
        post(url,data,dataType,successCB,errorCB,completeCB){
            ovo_ajax({
                type:"POST",
                url:url,
                data:data,
                dataType:dataType,
                success:successCB,
                error:errorCB,
                complete:completeCB
            })
        },
        get(url,dataType,successCB,errorCB,completeCB){
            ovo_ajax({
                type:"GET",
                url:url,
                dataType:dataType,
                success:successCB,
                error:errorCB,
                complete:completeCB
            })
        }
    }
})();
